/**
 * @name Room
 * @author darcrand
 * @desc
 */

import React, { Component } from 'react'
import { toJS } from 'mobx'
import { inject, observer } from 'mobx-react'
import store from 'store'
import { encrypt, decrypt } from '@/utils/crypto-aes'
import io from 'socket.io-client'
import { get } from '@/utils/aixos'

import Header from './Header'
import MessageView from './MessageView'
import MessageInput from './MessageInput'

import styles from './styles.module.less'

const STORAGE_KEY = '_the_local_chat_room_records'
const MAX_RECORD_LENGTH = 1000

@inject('UserStore')
@observer
class Room extends Component {
  socket = null

  state = { messages: [] }

  componentDidMount() {
    if (!this.props.UserStore.isLogged) {
      this.props.history.replace('/entry')
    } else {
      this.initSocket()
      this.initRecords()
    }
  }

  componentWillUnmount() {
    this.socket && this.socket.close()
  }

  initSocket = async () => {
    const res = await get('/socket/connect')
    if (res.code !== 20000) {
      return
    }
    const socketUrl = res.data
    this.socket = io.connect(socketUrl)

    // 普通信息
    this.socket.on('server-message', data => {})

    // 聊天记录信息
    this.socket.on('chat-update', res => {
      const { info } = this.props.UserStore
      const { messages } = this.state
      const isSelf = res.user.id === info.id
      const last = messages[messages.length - 1]
      const shouldShowDate = !last || res.date - last.date > 30000
      const transfedData = { ...res, isSelf, shouldShowDate }
      const nextMessages = messages.concat(transfedData)

      // cache
      const encode = encrypt(nextMessages)
      store.set(STORAGE_KEY, encode)

      this.setState({ messages: nextMessages })
    })
  }

  initRecords = () => {
    const encode = store.get(STORAGE_KEY) || ''
    const prevMessages = decrypt(encode) || []

    const arr = prevMessages
      .reverse()
      .slice(0, MAX_RECORD_LENGTH)
      .reverse()
    this.setState({ messages: arr })
  }

  onSend = message => {
    this.socket.emit('client-message', {
      user: toJS(this.props.UserStore.info),
      message,
      date: Date.now()
    })
  }

  render() {
    return (
      <div className={styles.container}>
        <Header />
        <MessageView messages={this.state.messages} />
        <MessageInput onSend={this.onSend} />
      </div>
    )
  }
}

export default Room
